package com.google.code.virtualhockey.vhx.sds

import com.google.appengine.api.datastore.Entity
import com.google.code.virtualhockey.vhx.sds.fields.SField
import java.lang.reflect.Constructor

/**
 * Should be implemented by all objects providing meta data about a persistable class.
 *
 * @param A the class that is described by this metadata object
 */
trait STMetaData[A <: STEntity[A]] {
  protected[sds] val cls: Class[A]
  protected[sds] val kind: String
  protected[sds] val fields: List[SField]
  private var constructor: Option[Constructor[A]] = None

  /**
   * Transforms the given GAE entity into an SDS entity.
   *
   * @param ent the entity to be transformed
   * @return the transformed entity
   */
  def toSds( ent: Entity ): A = {
    val instance = newSdsInstance()
    instance.fromGae( ent, this )
    instance
  }

  /**
   * Creates a new instance of A by using the defined no-arg constructor.
   */
  private def newSdsInstance(): A = {
    if ( constructor == None ) {
      constructor = Some( cls.getDeclaredConstructor() )
      constructor.get.setAccessible( true )
    }
    constructor.get.newInstance()
  }
}
